package com.example.socketio.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.UUID;

import org.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import com.corundumstudio.socketio.SocketIOServer;
import com.example.socketio.entity.FileResponse;

import jakarta.annotation.Resource;


@CrossOrigin(origins="http://localhost:5173")
@RestController
public class FileUploadController {
	
	private static final Logger logger = LoggerFactory.getLogger(FileUploadController.class);
	
	@Resource
	private SocketIOServer socketIOServer;
	
	
	@PostMapping("/upload")
	public ResponseEntity<?> uploadFile(@RequestParam("file") MultipartFile file,
										@RequestParam("username") String userName,
										@RequestParam("useravata") String useravata,
										
										@RequestParam("filename") String fileName,
	                                     @RequestHeader(value = "Content-Range", required = false) String contentRange) throws IOException, JSONException {
	    // Parse the Content-Range header to get the range of bytes being uploaded
	    long start = 0;
	    long end = file.getSize();
	    long fileSize = 0;
	    if (contentRange != null) {
	        String[] range = contentRange.split(" ")[1].split("/")[0].split("-");
	        String fileSizeStr = contentRange.split(" ")[1].split("/")[1];
	        start = Long.parseLong(range[0]);
	        end = Long.parseLong(range[1]);
	        fileSize = Long.parseLong(fileSizeStr);
	    }
	    String decodedFileName = URLDecoder.decode(fileName, StandardCharsets.UTF_8);

	    String uuidFileName = rename(decodedFileName,userName);
//	    logger.info("fileName="+uuidFileName);
	    // Save the chunk to a temporary file
	    File tempFile = new File("/Users/shirongxin/tmp/upload/"+uuidFileName);
	    try (RandomAccessFile raf = new RandomAccessFile(tempFile, "rw")) {
	        raf.seek(start);
	        raf.write(file.getBytes());
	    } catch (IOException e) {
	        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
	    }

	    // Emit an event via Socket.IO when the upload is complete
	    if (end == fileSize) {
	    	// 修改文件名字
	    	FileResponse res = new FileResponse();
	    	String enCodeUuidFileName = URLEncoder.encode(uuidFileName, StandardCharsets.UTF_8);
	    	res.setUrl("http://localhost:8080/download?fileName="+enCodeUuidFileName);
	    	res.setFrom(userName);
	    	res.setFromAvata(useravata);
	    	res.setTo(null);// TODO
	        socketIOServer.getBroadcastOperations().sendEvent("fileUploaded", res);
	    }

	    return ResponseEntity.ok().build();
	}


	@GetMapping("/download")
	public ResponseEntity<org.springframework.core.io.Resource> downloadFile(@RequestParam("fileName") String fileName) throws FileNotFoundException {
//	String uuidFileName = rename(fileName,userName);
	  String decodeFileName = 	URLDecoder.decode(fileName, StandardCharsets.UTF_8);
	  File file = new File("/Users/shirongxin/tmp/upload/" + decodeFileName);
	  InputStreamResource resource = new InputStreamResource(new FileInputStream(file));

	  HttpHeaders headers = new HttpHeaders();
	  headers.add(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");
	  headers.add(HttpHeaders.CONTENT_TYPE, "application/octet-stream");

	  return ResponseEntity.ok()
	      .headers(headers)
	      .contentLength(file.length())
	      .body(resource);
	}
	
	
	public static String rename(String oldFilename,String addBeforeDot) {
//        String uniqueFilename = generateUniqueFilename();
        String[] parts = oldFilename.split("\\."); // 注意要通过双反斜杠对点进行转义
        String ext = parts[parts.length - 1];
        String prefix = oldFilename.substring(0, oldFilename.length() - ext.length() - 1);
        return prefix + "-" + addBeforeDot + "." + ext;
    }

    private static String generateUniqueFilename() {
        Date now = new Date();
        UUID uuid = UUID.randomUUID();
        return String.format("%tY%<tm%<td-%s", now, uuid.toString());
    }


}
